/**
 * Created by LiH on 2018/8/21.
 */
import ZCToast from '../components/ZuicoolToast'

let $vm;
let timeStamp;
const fadeOutDuration = 500;

function debounce(duration, fn) {
  timeStamp = Date.now();
  return setTimeout(function () {
    const interval = Date.now() - timeStamp;

    if(interval >= duration){
      fn()
    }
  }, duration)
}

export default {
  install(Vue) {
    const Toast = Vue.extend(ZCToast);

    if(!$vm) {
      $vm = new Toast({
        el: document.createElement('div')
      });

      document.body.appendChild($vm.$el)
    }

    Vue.prototype.$ZCToast = Vue.$ZCToast = {
      _debounceTimeout: null,
      _animationTimeout: null,

      _resetStyle() {
        $vm.$el.style.transition = '';
        $vm.$el.style.opacity = '1';
      },

      _fadeOut(duration = 500) {
        $vm.$el.style.transition = `opacity ${duration / 1000}s`;
        $vm.$el.style.opacity = '0';
      },

      _clearTimeout(timeout) {
        if(!!this[timeout]){
          clearTimeout(this[timeout]);
          this[timeout] = null;
        }
      },

      _setPosition(position) {
        switch(position) {
          case 'top':
            $vm.$el.style.top = '15%';
            break;
          case 'bottom':
            $vm.$el.style.top = '85%';
            break;
          default:
            $vm.$el.style.top = '50%';
        }
      },

      show(conf) {
        let content, duration = 2, position = 'middle';

        if(String(conf) === '[object Object]'){
          ({content, duration, position} = conf);
        } else if(typeof conf === 'string'){
          content = conf;
        } else {
          throw new TypeError('invalid params')
        }

        timeStamp = Date.now();
        this._resetStyle();
        this._setPosition(position);
        $vm.content = content;
        $vm.visible = true;
        this._debounceTimeout = debounce(duration * 1000, () => {
          this._fadeOut(fadeOutDuration);
          this._animationTimeout = setTimeout(function () {
            if(Date.now() - timeStamp >= fadeOutDuration){
              $vm.visible = false;
            }
          }, 500)
        })
      },

      hide() {
        this._clearTimeout('_debounceTimeout');
        this._clearTimeout('_animationTimeout');
        $vm.visible = false;
      }
    };

    Vue.mixin({
      created() {
        this.$ZCToast = Vue.$ZCToast;
      }
    })
  }
}
